{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Forecasting with XGBoost, LightGBM and other Gradient Boosting models\n",
    "\n",
    "Gradient boosting models have gained popularity in the machine learning community due to their ability to achieve excellent results in a wide range of use cases, including both regression and classification. Although these models have traditionally been less common in forecasting, recent research has shown that they can be highly effective in this domain. Some of the key advantages of using gradient boosting models for forecasting include:\n",
    "\n",
    "+ The ease with which exogenous variables, in addition to autoregressive variables, can be incorporated into the model.\n",
    "\n",
    "+ The ability to capture non-linear relationships between variables.\n",
    "\n",
    "+ High scalability, which enables the models to handle large volumes of data.\n",
    "\n",
    "There are several popular implementations of gradient boosting in Python, with four of the most popular being [XGBoost](https://xgboost.readthedocs.io/en/stable/index.html), [LightGBM](https://lightgbm.readthedocs.io/en/latest/), [scikit-learn HistGradientBoostingRegressor](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.HistGradientBoostingRegressor.html#sklearn.ensemble.HistGradientBoostingRegressor) and [CatBoost](https://catboost.ai/). All of these libraries follow the scikit-learn API, making them compatible with skforecast.\n",
    "\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"admonition note\" name=\"html-admonition\" style=\"background: rgba(0,184,212,.1); padding-top: 0px; padding-bottom: 6px; border-radius: 8px; border-left: 8px solid #00b8d4; border-color: #00b8d4; padding-left: 10px; padding-right: 10px;\">\n",
    "\n",
    "<p class=\"title\">\n",
    "    <i style=\"font-size: 18px; color:#00b8d4;\"></i>\n",
    "    <b style=\"color: #00b8d4;\">&#9998 Note</b>\n",
    "</p>\n",
    "\n",
    "<p>\n",
    "All of the gradient boosting libraries mentioned above - <b>XGBoost</b>, <b>Lightgbm</b>, <b>HistGradientBoostingRegressor</b>, and <b>CatBoost</b> - can handle categorical features natively, but they require specific encoding techniques that may not be entirely intuitive. Detailed information can be found in <a href=\"../user_guides/categorical-features.html#native-implementation-for-categorical-features\">categorical features</a> and in this two use cases:\n",
    "\n",
    "<ul>\n",
    "<li><a href=\"https://cienciadedatos.net/documentos/py39-forecasting-time-series-with-skforecast-xgboost-lightgbm-catboost\">Forecasting time series with gradient boosting</a></li>\n",
    "\n",
    "<li><a href=\"https://www.cienciadedatos.net/documentos/py56-forecasting-time-series-with-xgboost.html\">Forecasting with XGBoost</a></li>\n",
    "\n",
    "<li><a href=\"https://cienciadedatos.net/documentos/py29-forecasting-electricity-power-demand-python\">Forecasting energy demand with machine learning</a></li>\n",
    "</ul>\n",
    "</p>\n",
    "\n",
    "<p>\n",
    "<br>\n",
    "<b>XGBoost</b>, <b>Lightgbm</b> and <b>CatBoost</b> can benefit from GPU acceleration, which can significantly speed up the training process. To learn more about how to enable GPU acceleration, please refer to the following link: <a href=\"https://skforecast.org/latest/user_guides/skforecast-in-gpu\">Skforecast GPU acceleration</a>.\n",
    "</p>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"admonition note\" name=\"html-admonition\" style=\"background: rgba(0,191,191,.1); padding-top: 0px; padding-bottom: 6px; border-radius: 8px; border-left: 8px solid #00bfa5; border-color: #00bfa5; padding-left: 10px; padding-right: 10px;\">\n",
    "\n",
    "<p class=\"title\">\n",
    "    <i style=\"font-size: 18px; color:#00bfa5;\"></i>\n",
    "    <b style=\"color: #00bfa5;\">&#128161 Tip</b>\n",
    "</p>\n",
    "\n",
    "Tree-based models, including decision trees, random forests and gradient boosting machines (GBMs) have limitations when it comes to extrapolation, i.e. making predictions or estimates beyond the range of observed data. This limitation becomes particularly critical when forecasting time series data with a trend. Because these models cannot predict values beyond the observed range during training, their predicted values will deviate from the underlying trend.\n",
    "\n",
    "Several strategies have been proposed to address this challenge, with one of the most common approaches being the use of differentiation. The differentiation process involves computing the differences between consecutive observations in the time series. Instead of directly modeling the absolute values, the focus shifts to modeling the relative change ratios. Skforecast introduces the <code>differentiation</code> parameter within its forecaster classes to indicate that a differentiation process must be applied before training the model. It is worth noting that the entire differentiation process is automated and its effects are seamlessly reversed during the prediction phase. This ensures that the resulting forecast values are in the original scale of the time series data. \n",
    "\n",
    "For more details in this topic visit: <a href=\"https://www.cienciadedatos.net/documentos/py49-modelling-time-series-trend-with-tree-based-models.html\">Modelling time series trend with tree based models</a>."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Libraries and data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Libraries\n",
    "# ==============================================================================\n",
    "from xgboost import XGBRegressor\n",
    "from lightgbm import LGBMRegressor\n",
    "from skforecast.datasets import fetch_dataset\n",
    "from skforecast.preprocessing import RollingFeatures\n",
    "from skforecast.recursive import ForecasterRecursive"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">╭─────────────────────────────────── <span style=\"font-weight: bold\">h2o_exog</span> ────────────────────────────────────╮\n",
       "│ <span style=\"font-weight: bold\">Description:</span>                                                                    │\n",
       "│ Monthly expenditure ($AUD) on corticosteroid drugs that the Australian health   │\n",
       "│ system had between 1991 and 2008. Two additional variables (exog_1, exog_2) are │\n",
       "│ simulated.                                                                      │\n",
       "│                                                                                 │\n",
       "│ <span style=\"font-weight: bold\">Source:</span>                                                                         │\n",
       "│ Hyndman R (2023). fpp3: Data for Forecasting: Principles and Practice (3rd      │\n",
       "│ Edition). http://pkg.robjhyndman.com/fpp3package/,                              │\n",
       "│ https://github.com/robjhyndman/fpp3package, http://OTexts.com/fpp3.             │\n",
       "│                                                                                 │\n",
       "│ <span style=\"font-weight: bold\">URL:</span>                                                                            │\n",
       "│ https://raw.githubusercontent.com/skforecast/skforecast-                        │\n",
       "│ datasets/main/data/h2o_exog.csv                                                 │\n",
       "│                                                                                 │\n",
       "│ <span style=\"font-weight: bold\">Shape:</span> 195 rows x 3 columns                                                     │\n",
       "╰─────────────────────────────────────────────────────────────────────────────────╯\n",
       "</pre>\n"
      ],
      "text/plain": [
       "╭─────────────────────────────────── \u001b[1mh2o_exog\u001b[0m ────────────────────────────────────╮\n",
       "│ \u001b[1mDescription:\u001b[0m                                                                    │\n",
       "│ Monthly expenditure ($AUD) on corticosteroid drugs that the Australian health   │\n",
       "│ system had between 1991 and 2008. Two additional variables (exog_1, exog_2) are │\n",
       "│ simulated.                                                                      │\n",
       "│                                                                                 │\n",
       "│ \u001b[1mSource:\u001b[0m                                                                         │\n",
       "│ Hyndman R (2023). fpp3: Data for Forecasting: Principles and Practice (3rd      │\n",
       "│ Edition). http://pkg.robjhyndman.com/fpp3package/,                              │\n",
       "│ https://github.com/robjhyndman/fpp3package, http://OTexts.com/fpp3.             │\n",
       "│                                                                                 │\n",
       "│ \u001b[1mURL:\u001b[0m                                                                            │\n",
       "│ https://raw.githubusercontent.com/skforecast/skforecast-                        │\n",
       "│ datasets/main/data/h2o_exog.csv                                                 │\n",
       "│                                                                                 │\n",
       "│ \u001b[1mShape:\u001b[0m 195 rows x 3 columns                                                     │\n",
       "╰─────────────────────────────────────────────────────────────────────────────────╯\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Download data\n",
    "# ==============================================================================\n",
    "data = fetch_dataset(\"h2o_exog\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Data preprocessing\n",
    "# ==============================================================================\n",
    "data.index.name = 'date'\n",
    "steps = 36\n",
    "data_train = data.iloc[:-steps, :]\n",
    "data_test  = data.iloc[-steps:, :]"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Forecaster LightGBM"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "    <style>\n",
       "        .container-f52b34f675f0445f9f9c1f875982a663 {\n",
       "            font-family: 'Arial', sans-serif;\n",
       "            font-size: 0.9em;\n",
       "            color: #333333;\n",
       "            border: 1px solid #ddd;\n",
       "            background-color: #f0f8ff;\n",
       "            padding: 5px 15px;\n",
       "            border-radius: 8px;\n",
       "            max-width: 600px;\n",
       "            #margin: auto;\n",
       "        }\n",
       "        .container-f52b34f675f0445f9f9c1f875982a663 h2 {\n",
       "            font-size: 1.5em;\n",
       "            color: #222222;\n",
       "            border-bottom: 2px solid #ddd;\n",
       "            padding-bottom: 5px;\n",
       "            margin-bottom: 15px;\n",
       "            margin-top: 5px;\n",
       "        }\n",
       "        .container-f52b34f675f0445f9f9c1f875982a663 details {\n",
       "            margin: 10px 0;\n",
       "        }\n",
       "        .container-f52b34f675f0445f9f9c1f875982a663 summary {\n",
       "            font-weight: bold;\n",
       "            font-size: 1.1em;\n",
       "            color: #000000;\n",
       "            cursor: pointer;\n",
       "            margin-bottom: 5px;\n",
       "            background-color: #b3dbfd;\n",
       "            padding: 5px;\n",
       "            border-radius: 5px;\n",
       "        }\n",
       "        .container-f52b34f675f0445f9f9c1f875982a663 summary:hover {\n",
       "            color: #000000;\n",
       "            background-color: #e0e0e0;\n",
       "        }\n",
       "        .container-f52b34f675f0445f9f9c1f875982a663 ul {\n",
       "            font-family: 'Courier New', monospace;\n",
       "            list-style-type: none;\n",
       "            padding-left: 20px;\n",
       "            margin: 10px 0;\n",
       "            line-height: normal;\n",
       "        }\n",
       "        .container-f52b34f675f0445f9f9c1f875982a663 li {\n",
       "            margin: 5px 0;\n",
       "            font-family: 'Courier New', monospace;\n",
       "        }\n",
       "        .container-f52b34f675f0445f9f9c1f875982a663 li strong {\n",
       "            font-weight: bold;\n",
       "            color: #444444;\n",
       "        }\n",
       "        .container-f52b34f675f0445f9f9c1f875982a663 li::before {\n",
       "            content: \"- \";\n",
       "            color: #666666;\n",
       "        }\n",
       "        .container-f52b34f675f0445f9f9c1f875982a663 a {\n",
       "            color: #001633;\n",
       "            text-decoration: none;\n",
       "        }\n",
       "        .container-f52b34f675f0445f9f9c1f875982a663 a:hover {\n",
       "            color: #359ccb; \n",
       "        }\n",
       "    </style>\n",
       "    \n",
       "        <div class=\"container-f52b34f675f0445f9f9c1f875982a663\">\n",
       "            <p style=\"font-size: 1.5em; font-weight: bold; margin-block-start: 0.83em; margin-block-end: 0.83em;\">ForecasterRecursive</p>\n",
       "            <details open>\n",
       "                <summary>General Information</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Estimator:</strong> LGBMRegressor</li>\n",
       "                    <li><strong>Lags:</strong> [1 2 3 4 5 6 7 8]</li>\n",
       "                    <li><strong>Window features:</strong> ['roll_mean_7']</li>\n",
       "                    <li><strong>Window size:</strong> 8</li>\n",
       "                    <li><strong>Series name:</strong> y</li>\n",
       "                    <li><strong>Exogenous included:</strong> True</li>\n",
       "                    <li><strong>Weight function included:</strong> False</li>\n",
       "                    <li><strong>Differentiation order:</strong> None</li>\n",
       "                    <li><strong>Creation date:</strong> 2025-11-26 15:10:44</li>\n",
       "                    <li><strong>Last fit date:</strong> 2025-11-26 15:10:47</li>\n",
       "                    <li><strong>Skforecast version:</strong> 0.19.0</li>\n",
       "                    <li><strong>Python version:</strong> 3.12.11</li>\n",
       "                    <li><strong>Forecaster id:</strong> None</li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Exogenous Variables</summary>\n",
       "                <ul>\n",
       "                    exog_1, exog_2\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Data Transformations</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Transformer for y:</strong> None</li>\n",
       "                    <li><strong>Transformer for exog:</strong> None</li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Training Information</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Training range:</strong> [Timestamp('1992-04-01 00:00:00'), Timestamp('2005-06-01 00:00:00')]</li>\n",
       "                    <li><strong>Training index type:</strong> DatetimeIndex</li>\n",
       "                    <li><strong>Training index frequency:</strong> <MonthBegin></li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Estimator Parameters</summary>\n",
       "                <ul>\n",
       "                    {'boosting_type': 'gbdt', 'class_weight': None, 'colsample_bytree': 1.0, 'importance_type': 'split', 'learning_rate': 0.1, 'max_depth': -1, 'min_child_samples': 20, 'min_child_weight': 0.001, 'min_split_gain': 0.0, 'n_estimators': 100, 'n_jobs': None, 'num_leaves': 31, 'objective': None, 'random_state': 123, 'reg_alpha': 0.0, 'reg_lambda': 0.0, 'subsample': 1.0, 'subsample_for_bin': 200000, 'subsample_freq': 0, 'verbose': -1}\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Fit Kwargs</summary>\n",
       "                <ul>\n",
       "                    {}\n",
       "                </ul>\n",
       "            </details>\n",
       "            <p>\n",
       "                <a href=\"https://skforecast.org/0.19.0/api/forecasterrecursive.html\">&#128712 <strong>API Reference</strong></a>\n",
       "                &nbsp;&nbsp;\n",
       "                <a href=\"https://skforecast.org/0.19.0/user_guides/autoregressive-forecaster.html\">&#128462 <strong>User Guide</strong></a>\n",
       "            </p>\n",
       "        </div>\n",
       "        "
      ],
      "text/plain": [
       "=================== \n",
       "ForecasterRecursive \n",
       "=================== \n",
       "Estimator: LGBMRegressor \n",
       "Lags: [1 2 3 4 5 6 7 8] \n",
       "Window features: ['roll_mean_7'] \n",
       "Window size: 8 \n",
       "Series name: y \n",
       "Exogenous included: True \n",
       "Exogenous names: exog_1, exog_2 \n",
       "Transformer for y: None \n",
       "Transformer for exog: None \n",
       "Weight function included: False \n",
       "Differentiation order: None \n",
       "Training range: [Timestamp('1992-04-01 00:00:00'), Timestamp('2005-06-01 00:00:00')] \n",
       "Training index type: DatetimeIndex \n",
       "Training index frequency: <MonthBegin> \n",
       "Estimator parameters: \n",
       "    {'boosting_type': 'gbdt', 'class_weight': None, 'colsample_bytree': 1.0,\n",
       "    'importance_type': 'split', 'learning_rate': 0.1, 'max_depth': -1,\n",
       "    'min_child_samples': 20, 'min_child_weight': 0.001, 'min_split_gain': 0.0,\n",
       "    'n_estimators': 100, 'n_jobs': None, 'num_leaves': 31, 'objective': None,\n",
       "    'random_state': 123, 'reg_alpha': 0.0, 'reg_lambda': 0.0, 'subsample': 1.0,\n",
       "    'subsample_for_bin': 200000, 'subsample_freq': 0, 'verbose': -1} \n",
       "fit_kwargs: {} \n",
       "Creation date: 2025-11-26 15:10:44 \n",
       "Last fit date: 2025-11-26 15:10:47 \n",
       "Skforecast version: 0.19.0 \n",
       "Python version: 3.12.11 \n",
       "Forecaster id: None "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Create and fit forecaster\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursive(\n",
    "                 estimator       = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags            = 8,\n",
    "                 window_features = RollingFeatures(stats=['mean'], window_sizes=[7]),\n",
    "             )\n",
    "\n",
    "forecaster.fit(y=data_train['y'], exog=data_train[['exog_1', 'exog_2']])\n",
    "forecaster"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2005-07-01    0.941524\n",
       "2005-08-01    0.927756\n",
       "2005-09-01    1.065236\n",
       "2005-10-01    1.088430\n",
       "2005-11-01    1.083675\n",
       "2005-12-01    1.168836\n",
       "2006-01-01    0.967025\n",
       "2006-02-01    0.751336\n",
       "2006-03-01    0.816116\n",
       "2006-04-01    0.801357\n",
       "Freq: MS, Name: pred, dtype: float64"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Predict\n",
    "# ==============================================================================\n",
    "forecaster.predict(steps=10, exog=data_test[['exog_1', 'exog_2']])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>feature</th>\n",
       "      <th>importance</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>exog_2</td>\n",
       "      <td>121</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>lag_2</td>\n",
       "      <td>94</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>lag_1</td>\n",
       "      <td>59</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>exog_1</td>\n",
       "      <td>43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>lag_6</td>\n",
       "      <td>42</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>lag_4</td>\n",
       "      <td>41</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>lag_5</td>\n",
       "      <td>37</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>lag_8</td>\n",
       "      <td>25</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>lag_7</td>\n",
       "      <td>22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>lag_3</td>\n",
       "      <td>14</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>roll_mean_7</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        feature  importance\n",
       "10       exog_2         121\n",
       "1         lag_2          94\n",
       "0         lag_1          59\n",
       "9        exog_1          43\n",
       "5         lag_6          42\n",
       "3         lag_4          41\n",
       "4         lag_5          37\n",
       "7         lag_8          25\n",
       "6         lag_7          22\n",
       "2         lag_3          14\n",
       "8   roll_mean_7          11"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Feature importances\n",
    "# ==============================================================================\n",
    "forecaster.get_feature_importances()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Forecaster XGBoost"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "    <style>\n",
       "        .container-bdb7c4352d2c498680c52813fdddc9a1 {\n",
       "            font-family: 'Arial', sans-serif;\n",
       "            font-size: 0.9em;\n",
       "            color: #333333;\n",
       "            border: 1px solid #ddd;\n",
       "            background-color: #f0f8ff;\n",
       "            padding: 5px 15px;\n",
       "            border-radius: 8px;\n",
       "            max-width: 600px;\n",
       "            #margin: auto;\n",
       "        }\n",
       "        .container-bdb7c4352d2c498680c52813fdddc9a1 h2 {\n",
       "            font-size: 1.5em;\n",
       "            color: #222222;\n",
       "            border-bottom: 2px solid #ddd;\n",
       "            padding-bottom: 5px;\n",
       "            margin-bottom: 15px;\n",
       "            margin-top: 5px;\n",
       "        }\n",
       "        .container-bdb7c4352d2c498680c52813fdddc9a1 details {\n",
       "            margin: 10px 0;\n",
       "        }\n",
       "        .container-bdb7c4352d2c498680c52813fdddc9a1 summary {\n",
       "            font-weight: bold;\n",
       "            font-size: 1.1em;\n",
       "            color: #000000;\n",
       "            cursor: pointer;\n",
       "            margin-bottom: 5px;\n",
       "            background-color: #b3dbfd;\n",
       "            padding: 5px;\n",
       "            border-radius: 5px;\n",
       "        }\n",
       "        .container-bdb7c4352d2c498680c52813fdddc9a1 summary:hover {\n",
       "            color: #000000;\n",
       "            background-color: #e0e0e0;\n",
       "        }\n",
       "        .container-bdb7c4352d2c498680c52813fdddc9a1 ul {\n",
       "            font-family: 'Courier New', monospace;\n",
       "            list-style-type: none;\n",
       "            padding-left: 20px;\n",
       "            margin: 10px 0;\n",
       "            line-height: normal;\n",
       "        }\n",
       "        .container-bdb7c4352d2c498680c52813fdddc9a1 li {\n",
       "            margin: 5px 0;\n",
       "            font-family: 'Courier New', monospace;\n",
       "        }\n",
       "        .container-bdb7c4352d2c498680c52813fdddc9a1 li strong {\n",
       "            font-weight: bold;\n",
       "            color: #444444;\n",
       "        }\n",
       "        .container-bdb7c4352d2c498680c52813fdddc9a1 li::before {\n",
       "            content: \"- \";\n",
       "            color: #666666;\n",
       "        }\n",
       "        .container-bdb7c4352d2c498680c52813fdddc9a1 a {\n",
       "            color: #001633;\n",
       "            text-decoration: none;\n",
       "        }\n",
       "        .container-bdb7c4352d2c498680c52813fdddc9a1 a:hover {\n",
       "            color: #359ccb; \n",
       "        }\n",
       "    </style>\n",
       "    \n",
       "        <div class=\"container-bdb7c4352d2c498680c52813fdddc9a1\">\n",
       "            <p style=\"font-size: 1.5em; font-weight: bold; margin-block-start: 0.83em; margin-block-end: 0.83em;\">ForecasterRecursive</p>\n",
       "            <details open>\n",
       "                <summary>General Information</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Estimator:</strong> XGBRegressor</li>\n",
       "                    <li><strong>Lags:</strong> [1 2 3 4 5 6 7 8]</li>\n",
       "                    <li><strong>Window features:</strong> ['roll_mean_7']</li>\n",
       "                    <li><strong>Window size:</strong> 8</li>\n",
       "                    <li><strong>Series name:</strong> y</li>\n",
       "                    <li><strong>Exogenous included:</strong> True</li>\n",
       "                    <li><strong>Weight function included:</strong> False</li>\n",
       "                    <li><strong>Differentiation order:</strong> None</li>\n",
       "                    <li><strong>Creation date:</strong> 2025-11-26 15:10:47</li>\n",
       "                    <li><strong>Last fit date:</strong> 2025-11-26 15:10:48</li>\n",
       "                    <li><strong>Skforecast version:</strong> 0.19.0</li>\n",
       "                    <li><strong>Python version:</strong> 3.12.11</li>\n",
       "                    <li><strong>Forecaster id:</strong> None</li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Exogenous Variables</summary>\n",
       "                <ul>\n",
       "                    exog_1, exog_2\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Data Transformations</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Transformer for y:</strong> None</li>\n",
       "                    <li><strong>Transformer for exog:</strong> None</li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Training Information</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Training range:</strong> [Timestamp('1992-04-01 00:00:00'), Timestamp('2005-06-01 00:00:00')]</li>\n",
       "                    <li><strong>Training index type:</strong> DatetimeIndex</li>\n",
       "                    <li><strong>Training index frequency:</strong> <MonthBegin></li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Estimator Parameters</summary>\n",
       "                <ul>\n",
       "                    {'objective': 'reg:squarederror', 'base_score': None, 'booster': None, 'callbacks': None, 'colsample_bylevel': None, 'colsample_bynode': None, 'colsample_bytree': None, 'device': None, 'early_stopping_rounds': None, 'enable_categorical': True, 'eval_metric': None, 'feature_types': None, 'feature_weights': None, 'gamma': None, 'grow_policy': None, 'importance_type': None, 'interaction_constraints': None, 'learning_rate': None, 'max_bin': None, 'max_cat_threshold': None, 'max_cat_to_onehot': None, 'max_delta_step': None, 'max_depth': None, 'max_leaves': None, 'min_child_weight': None, 'missing': nan, 'monotone_constraints': None, 'multi_strategy': None, 'n_estimators': None, 'n_jobs': None, 'num_parallel_tree': None, 'random_state': 123, 'reg_alpha': None, 'reg_lambda': None, 'sampling_method': None, 'scale_pos_weight': None, 'subsample': None, 'tree_method': None, 'validate_parameters': None, 'verbosity': None}\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Fit Kwargs</summary>\n",
       "                <ul>\n",
       "                    {}\n",
       "                </ul>\n",
       "            </details>\n",
       "            <p>\n",
       "                <a href=\"https://skforecast.org/0.19.0/api/forecasterrecursive.html\">&#128712 <strong>API Reference</strong></a>\n",
       "                &nbsp;&nbsp;\n",
       "                <a href=\"https://skforecast.org/0.19.0/user_guides/autoregressive-forecaster.html\">&#128462 <strong>User Guide</strong></a>\n",
       "            </p>\n",
       "        </div>\n",
       "        "
      ],
      "text/plain": [
       "=================== \n",
       "ForecasterRecursive \n",
       "=================== \n",
       "Estimator: XGBRegressor \n",
       "Lags: [1 2 3 4 5 6 7 8] \n",
       "Window features: ['roll_mean_7'] \n",
       "Window size: 8 \n",
       "Series name: y \n",
       "Exogenous included: True \n",
       "Exogenous names: exog_1, exog_2 \n",
       "Transformer for y: None \n",
       "Transformer for exog: None \n",
       "Weight function included: False \n",
       "Differentiation order: None \n",
       "Training range: [Timestamp('1992-04-01 00:00:00'), Timestamp('2005-06-01 00:00:00')] \n",
       "Training index type: DatetimeIndex \n",
       "Training index frequency: <MonthBegin> \n",
       "Estimator parameters: \n",
       "    {'objective': 'reg:squarederror', 'base_score': None, 'booster': None,\n",
       "    'callbacks': None, 'colsample_bylevel': None, 'colsample_bynode': None,\n",
       "    'colsample_bytree': None, 'device': None, 'early_stopping_rounds': None,\n",
       "    'enable_categorical': True, 'eval_metric': None, 'feature_types': None,\n",
       "    'feature_weights': None, 'gamma': None, 'grow_policy': None,\n",
       "    'importance_type': None, 'interaction_constraints': None, 'learning_rate':\n",
       "    None, 'max_bin': None, 'max_cat_threshold': None, 'max_cat_to_onehot': None,\n",
       "    'max_delta_step': None, 'max_depth': None, 'max_leaves': None,\n",
       "    'min_child_weight': None, 'missing': nan, 'monotone_constraints': None,\n",
       "    'multi_strategy': None, 'n_estimators': None, 'n_jobs': None,\n",
       "    'num_parallel_tree': None, 'random_state': 123, 'reg_alpha': None,\n",
       "    'reg_lambda': None, 'sampling_method': None, 'scale_pos_weight': None,\n",
       "    'subsample': None, 'tree_method': None, 'validate_parameters': None,\n",
       "    'verbosity': None} \n",
       "fit_kwargs: {} \n",
       "Creation date: 2025-11-26 15:10:47 \n",
       "Last fit date: 2025-11-26 15:10:48 \n",
       "Skforecast version: 0.19.0 \n",
       "Python version: 3.12.11 \n",
       "Forecaster id: None "
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Create and fit forecaster\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursive(\n",
    "                 estimator       = XGBRegressor(random_state=123, enable_categorical=True),\n",
    "                 lags            = 8,\n",
    "                 window_features = RollingFeatures(stats=['mean'], window_sizes=[7]),\n",
    "             )\n",
    "\n",
    "forecaster.fit(y=data_train['y'], exog=data_train[['exog_1', 'exog_2']])\n",
    "forecaster"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2005-07-01    0.881743\n",
       "2005-08-01    0.985714\n",
       "2005-09-01    1.070262\n",
       "2005-10-01    1.099444\n",
       "2005-11-01    1.116030\n",
       "2005-12-01    1.206317\n",
       "2006-01-01    0.977022\n",
       "2006-02-01    0.679524\n",
       "2006-03-01    0.740902\n",
       "2006-04-01    0.742273\n",
       "Freq: MS, Name: pred, dtype: float64"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Predict\n",
    "# ==============================================================================\n",
    "forecaster.predict(steps=10, exog=data_test[['exog_1', 'exog_2']])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>feature</th>\n",
       "      <th>importance</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>lag_1</td>\n",
       "      <td>0.299734</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>exog_2</td>\n",
       "      <td>0.255852</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>lag_2</td>\n",
       "      <td>0.105777</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>lag_7</td>\n",
       "      <td>0.100981</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>lag_5</td>\n",
       "      <td>0.083807</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>lag_8</td>\n",
       "      <td>0.063430</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>exog_1</td>\n",
       "      <td>0.055471</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>lag_4</td>\n",
       "      <td>0.017550</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>lag_6</td>\n",
       "      <td>0.010896</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>lag_3</td>\n",
       "      <td>0.004139</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>roll_mean_7</td>\n",
       "      <td>0.002362</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        feature  importance\n",
       "0         lag_1    0.299734\n",
       "10       exog_2    0.255852\n",
       "1         lag_2    0.105777\n",
       "6         lag_7    0.100981\n",
       "4         lag_5    0.083807\n",
       "7         lag_8    0.063430\n",
       "9        exog_1    0.055471\n",
       "3         lag_4    0.017550\n",
       "5         lag_6    0.010896\n",
       "2         lag_3    0.004139\n",
       "8   roll_mean_7    0.002362"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Feature importances\n",
    "# ==============================================================================\n",
    "forecaster.get_feature_importances()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "skforecast_py12",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.11"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": true,
   "title_cell": "Tabla de contenidos",
   "title_sidebar": "Tabla de contenidos",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "165px"
   },
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "position": {
    "height": "144.391px",
    "left": "1478px",
    "right": "20px",
    "top": "126px",
    "width": "350px"
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
